package com.jinly.ryder.jenkins.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jinly.ryder.jenkins.service.JenkinsBuildService;
import com.jinly.ryder.jenkins.service.JenkinsHttpService;
import com.jinly.ryder.jenkins.service.model.JenkinsBuild;
import com.jinly.ryder.jenkins.service.model.JenkinsQueue;
import com.jinly.ryder.jenkins.service.model.JenkinsStage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class JenkinsBuildServiceImpl implements JenkinsBuildService {

    private final JenkinsHttpService jenkinsHttpService;

    @Override
    public String build(String jobName) {
        String path = "/job/" + jobName + "/build";
        ResponseEntity<String> res = jenkinsHttpService.doPost(path, null);
        String location = res.getHeaders().getFirst("Location");
        if (location != null) {
            String queueId = location.substring(location.lastIndexOf("item/") + 5).replace("/", "");
            return queueId;
        }
        return null;
    }

    @Override
    public JenkinsQueue getQueue(String queueId) {
        String path = "/queue/item/" + queueId + "/api/json";
        String json = jenkinsHttpService.doGet(path);
        if (json != null) {
            JSONObject jsonObject = JSON.parseObject(json);
            JenkinsQueue queue = new JenkinsQueue();
            queue.setBlocked(jsonObject.getBoolean("blocked"));
            queue.setBuildable(jsonObject.getBoolean("buildable"));
            if (jsonObject.containsKey("cancelled")) {
                queue.setCancelled(jsonObject.getBoolean("cancelled"));
            }
            if (jsonObject.containsKey("executable")) {
                JSONObject executable = jsonObject.getJSONObject("executable");
                queue.setBuildNo(executable.getInteger("number"));
            }
            return queue;
        }
        return null;
    }

    @Override
    public JenkinsBuild getBuild(String jobName, Integer buildNo) {
        String buildJson = jenkinsHttpService.doGet("/job/" + jobName + "/" + buildNo + "/api/json");
        JSONObject buildJsonObject = JSONObject.parseObject(buildJson);
        JenkinsBuild jenkinsBuild = buildJsonObject.toJavaObject(JenkinsBuild.class);
        jenkinsBuild.setGitInfo(buildJsonObject);
        jenkinsBuild.setGitCommitLog(buildJsonObject);
        jenkinsBuild.getArtifacts().stream().forEach(a -> {
            a.setUrl(jenkinsBuild.getUrl() + "artifact/" + a.getRelativePath());
            a.setTimestamp(jenkinsBuild.getTimestamp());
        });
        return jenkinsBuild;
    }


    @Override
    public String getBuildConsole(String jobName, Integer buildNo) {
        return jenkinsHttpService.doGet("/job/" + jobName + "/" + buildNo + "/logText/progressiveText");
    }

    @Override
    public List<JenkinsStage> getBuildStages(String jobName, Integer buildNo) {
        String path = "/job/" + jobName + "/wfapi/runs?since=%23" + (buildNo - 5);
        String json = jenkinsHttpService.doGet(path);
        if (json != null) {
            return JSON.parseArray(json, JenkinsStage.class);
        }
        return Collections.emptyList();
    }
}
